package com.bolt.core.view.freemarker;

import com.bolt.common.utils.StrUtil;
import com.bolt.convention.exception.ServiceException;
import com.bolt.core.view.components.*;
import com.bolt.support.freemarker.DirectiveUtil;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2019/4/17.
 */
public class QueryFormModel extends TagModel {

    private String getId(Map params) {
        return DirectiveUtil.getString(params, "id");
    }

    private  String getAction(Map <String, TemplateModel> params) {
        return DirectiveUtil.getString(params, "action");
    }

    private String getPath(Map <String, TemplateModel> params) {
        return DirectiveUtil.getString(params, "path");
    }

    public String getDataGrid(Map <String, TemplateModel> params) {
        return DirectiveUtil.getString(params, "dataGrid");
    }


    @Override
    public ComponentsBase getUI(Map params) {
        if (getPageRepository().exists(getPath(params), getId(params))) {
            PageView pageView = getPageRepository().findPage(getPath(params));
            Form form = pageView.getForm(getId(params));
            if (StrUtil.isNotEmpty(getAction(params))) {
                form.setQueryAction(getAction(params));
            }
            return extractQueryForm(form, params);

        } else {
            throw new ServiceException("pageView:['" + getPath(params) + "'],form:['" + getId(params) + "'] not found");
        }

    }

    private QueryForm extractQueryForm(Form form, Map params) {
        QueryForm queryForm = new QueryForm();
        String action = getAction(params);
        String dataGrid = getDataGrid(params);
        queryForm.setAction(StrUtil.isEmpty(action) ? form.getQueryAction() : action);
        queryForm.setDataGrid(dataGrid);

        List <FormItem> newGroups = new ArrayList <>();
        for (List <FormItem> group : form.getGroup()) {
            newGroups.addAll(group);
        }
        newGroups.addAll(form.getHiddenFormItems());
        for (FormItem formItem : newGroups) {
            evaluateParams(queryForm, formItem);
            queryForm.addFormItems(formItem);
        }

        return queryForm;
    }

    @Override
    protected void populateParams(ComponentsBase component, Map <String, TemplateModel> params) {
        super.populateParams(component, params);
        QueryForm form = (QueryForm) component;
        List <FormItem> group = form.getGroup();
        group.forEach(k -> {
            k.setTemplateDir(form.getTemplateDir());
            k.setTheme(form.getTheme());
            k.setTemplateEngine(form.getTemplateEngine());
        });
    }

    private void evaluateParams(QueryForm queryForm, FormItem item) {
        if (!item.existParameter("placeholder")) {
            item.addDynamicParameters("placeholder", item.getLabel());
        }

        if (item.isQueryField() && StrUtil.isNotBlank(item.getMatchType())) {
            FormItem hiddenText = new FormItem();
            hiddenText.setType("hidden");
            hiddenText.setId("filters");
            hiddenText.addParameter("value", item.getName() + ":" + newName(item.getName(), item.getMatchType()));

            queryForm.addFormItems(hiddenText);
        }
    }

    private String newName(String name, String matchType) {
        if (StrUtil.isEmpty(matchType)) {
            return name;
        }
        StringBuffer newName = new StringBuffer("search[");

        if (StrUtil.indexOf(matchType, '_') > 0) {
            newName.append("'" + matchType + "'");
        } else {
            newName.append("'" + matchType.toUpperCase() + "_" + name + "'");
        }
        newName.append("]");
        return newName.toString();
    }


    @Override
    public void render(ComponentsBase component, Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException {
        QueryForm queryForm = (QueryForm) component;
        queryForm.start(getRequest(), getResponse(), env.getOut());
        for (FormItem item : queryForm.getGroup()) {
            if ("hidden".equals(item.getType())) {
                item.end(getRequest(), getResponse(), env.getOut());
            } else {
                Decorate decorate = Decorate.buildQueryFormColumnDecorate(item);
                decorate.start(getRequest(), getResponse(), env.getOut());
                decorate.end(getRequest(), getResponse(), env.getOut());
            }

        }
        queryForm.end(getRequest(), getResponse(), env.getOut());
    }
}

 